package yunjiao.javatutorials.guava.concurrent.log;

import yunjiao.javatutorials.guava.concurrent.ForwardingLock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * 生产环境建议
 *
 * @author yangyunjiao
 */
public class ProductionReadyLoggingLock extends ForwardingLock {
    private final Lock delegate;
    private final String name;
    private final boolean enableTiming;
    private final long slowLockThresholdMs;

    public ProductionReadyLoggingLock(Lock delegate, String name) {
        this(delegate, name, true, 100L);
    }

    public ProductionReadyLoggingLock(Lock delegate, String name,
                                      boolean enableTiming, long slowLockThresholdMs) {
        this.delegate = delegate;
        this.name = name;
        this.enableTiming = enableTiming;
        this.slowLockThresholdMs = slowLockThresholdMs;
    }

    @Override
    protected Lock delegate() {
        return delegate;
    }

    @Override
    public void lock() {
        long startTime = enableTiming ? System.currentTimeMillis() : 0;

        super.lock();

        if (enableTiming) {
            long duration = System.currentTimeMillis() - startTime;
            if (duration > slowLockThresholdMs) {
                logSlowLock(duration);
            }
        }
    }

    private void logSlowLock(long duration) {
        // 在生产环境中，应该使用适当的日志框架
        System.err.println("WARNING: Lock '" + name + "' took " + duration + "ms to acquire");
        // 这里可以添加更复杂的监控逻辑，如发送到监控系统
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        long startTime = enableTiming ? System.currentTimeMillis() : 0;

        boolean result = super.tryLock(time, unit);

        if (enableTiming && result) {
            long duration = System.currentTimeMillis() - startTime;
            if (duration > slowLockThresholdMs) {
                logSlowLock(duration);
            }
        }

        return result;
    }
}
